package com.demo.common;

import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;

/**
 * @author wangfengchen
 */
@Slf4j
public class ResultData<T> implements Serializable {

  private static final long serialVersionUID = 1L;

  private static final int SUCCESS_CODE = 200;
  private static final String SUCCESS_MSG = "success";
  private static final int FAIL_CODE = 500;
  private static final String FAIL_MSG = "service internal exception";
  private String requestId;
  private int code;
  private String message;
  private T data;


  public ResultData() {
  }

  public ResultData(String requestId, int code, String message, T data) {
    this.requestId = requestId;
    this.code = code;
    this.message = message;
    this.data = data;
  }

  /**
   * 返回失败，默认值
   *
   * @return
   */
  public static <T> ResultData<T> fail() {
    return setResult(null, FAIL_CODE, FAIL_MSG, null);
  }

  /**
   * 返回失败，可以传 code
   *
   * @param code
   * @return
   */
  public static <T> ResultData<T> fail(int code) {
    return setResult(null, code, FAIL_MSG, null);
  }

  /**
   * 返回失败，可以传 msg
   *
   * @param msg
   * @return
   */
  public static <T> ResultData<T> fail(String msg) {
    return setResult(null, FAIL_CODE, msg, null);
  }

  /**
   * 返回失败，可以传 code 和 msg
   *
   * @param code
   * @param msg
   * @return
   */
  public static <T> ResultData<T> fail(int code, String msg) {
    return setResult(null, code, msg, null);
  }

  /**
   * 返回失败，可以传 requestId 和 msg
   *
   * @param msg
   * @param requestId
   * @param <T>
   * @return
   */
  public static <T> ResultData<T> fail(String requestId, String msg) {
    return setResult(requestId, FAIL_CODE, msg, null);
  }

  /**
   * 返回失败，可以传 requestId 和 code 和 msg
   *
   * @param code
   * @param msg
   * @param requestId
   * @param <T>
   * @return
   */
  public static <T> ResultData<T> fail(String requestId, int code, String msg) {
    return setResult(requestId, code, msg, null);
  }

  /**
   * 返回成功，默认值
   *
   * @return
   */
  public static <T> ResultData<T> success() {
    return setResult(null, SUCCESS_CODE, SUCCESS_MSG, null);
  }

  /**
   * 返回成功，可以传 data
   *
   * @param data
   * @return
   */
  public static <T> ResultData<T> success(T data) {
    return setResult(null, SUCCESS_CODE, SUCCESS_MSG, data);
  }

  /**
   * 返回成功，可以传 requestId 和 data
   *
   * @param requestId
   * @param data
   * @param <T>
   * @return
   */
  public static <T> ResultData<T> success(String requestId, T data) {
    return setResult(requestId, SUCCESS_CODE, SUCCESS_MSG, data);
  }

  /**
   * 返回成功，可以传 requestId 和 msg 和 data
   *
   * @param msg
   * @return
   */
  public static <T> ResultData<T> success(String requestId, String msg, T data) {
    return setResult(requestId, SUCCESS_CODE, msg, data);
  }

  /**
   * 通用封装
   *
   * @param requestId
   * @param code
   * @param msg
   * @param data
   * @param <T>
   * @return
   */
  private static <T> ResultData<T> setResult(String requestId, Integer code, String msg, T data) {
    return new ResultData<>(requestId, code, msg, data);
  }

  /**
   * 响应json数据给前端
   *
   * @param response
   * @param obj
   */
  public static void buildJsonMsg(HttpServletResponse response, Object obj) {
    response.setContentType("application/json; charset=utf-8");
    try (PrintWriter writer = response.getWriter()) {
      writer.print(JSON.toJSON(obj));
      response.flushBuffer();
    } catch (IOException e) {
      log.warn("响应json数据给前端异常，e = {}", ExceptionUtils.getStackTrace(e));
    }
  }

  /**
   * 响应HTML数据给前端
   *
   * @param response
   * @param obj
   */
  public static void buildHtmlMsg(HttpServletResponse response, Object obj) {
    response.setContentType("text/html; charset=utf-8");
    try (PrintWriter writer = response.getWriter()) {
      writer.write(JSON.toJSONString(obj));
      writer.flush();
    } catch (IOException e) {
      log.warn("响应HTML数据给前端异常，e = {}", ExceptionUtils.getStackTrace(e));
    }
  }

  public int getCode() {
    return code;
  }

  public void setMessage(String message) {
    this.message = message;
  }

  public String getMessage() {
    return message;
  }

  public T getData() {
    return data;
  }

  public String getRequestId() {
    return requestId;
  }

  public void setRequestId(String requestId) {
    this.requestId = requestId;
  }


}
